package com.ddsso.auth.web.util;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;

import java.io.Serializable;

/**
 * 基于<b>shiro</b>框架会话的工具类
 * <p>
 * 提供方便操作<b>shiro</b>框架会话的一些静态方法
 * 
 * @author 464281
 * @see SecurityUtils
 * @see Session
 * @see Subject
 */
public class SessionUtil {

	/**
	 * 根据key获取其在会话中的attribute
	 * <p>
	 * 会话不存在时不强制创建
	 * 
	 * @param key
	 *            key值
	 * @return 对应的attribute
	 * 
	 * @see #getSession(boolean)
	 * @see Session#getAttribute(Object)
	 * @see javax.servlet.http.HttpSession#getAttribute(String)
	 */
	@SuppressWarnings("unchecked")
	public static final <T> T getAttribute(String key) {
		Session session = getSession(false);
		return (null != session ? (T) session.getAttribute(key) : null);
	}

	/**
	 * 设置会话内容
	 * <p>
	 * 配合分布式session，value必须是可序列化的
	 * 
	 * @param key
	 *            key值
	 * @param value
	 *            value值
	 * 
	 * @see Session#setAttribute(Object, Object)
	 * @see javax.servlet.http.HttpSession#setAttribute(String, Object)
	 */
	public static final void setAttribute(String key, Serializable value) {
		Session session = getSession();
		session.setAttribute(key, value);
	}

	/**
	 * 根据key删除会话attribute
	 * 
	 * @param key
	 *            key值
	 * @return value值
	 * @see Session#removeAttribute(Object)
	 */
	@SuppressWarnings("unchecked")
	public static final <T> T removeAttriubute(String key) {
		Session session = getSession();
		return (T) session.removeAttribute(key);
	}

	/**
	 * 获取<b>shiro</b>框架的会话
	 * 
	 * <p>
	 * <b>shiro</b>框架的会话是保存在本地线程变量中的，在一次请求中，能保持获取到会话内容。对于weblogic、</br>
	 * jetty等servlet容器，<code>404</code>等请求将获取不到分布式session，因为处理</br>
	 * </br> 对象，导致获取不到分布式session，使用本方法，可以获取到
	 * 
	 * @param created
	 *            不存在时是否创建，<code>TRUE</code>表示强制创建
	 * @return 会话
	 * @see Session
	 * @see Subject
	 */
	public static final Session getSession(boolean created) {
		Subject subject = SecurityUtils.getSubject();
		return subject.getSession(created);
	}

	/**
	 * 获取<b>shiro</b>框架的会话
	 * <p>
	 * 不存在时强制创建
	 * 
	 * @return 会话
	 * @see #getSession(boolean)
	 * @see Session
	 */
	public static final Session getSession() {
		return getSession(true);
	}
}
